﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;


namespace ThePresenter.Polls.Data
{
	public class PollAnswersSet : ObservableCollection<AnswerData>, INotifyPropertyChanged
	{
		#region Fields
		private Dictionary<String, int> _Statistics;

		public OptionsData Options;
		#endregion


		#region Properties
		/// <summary>
		/// Gets the statistics.
		/// </summary>
		/// <value>The statistics.</value>
		public Dictionary<String, int> Statistics
		{
			get
			{
				if (_Statistics == null)
				{
					this.UpdateStats();
				}
				return _Statistics;
			}
		}
		#endregion


		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="PollAnswersSet"/> class.
		/// </summary>
		public PollAnswersSet()
		{
		}
		#endregion


		#region Methods
		/// <summary>
		/// Updates the stats.
		/// </summary>
		private void UpdateStats()
		{
			Dictionary<String, int> stats = new Dictionary<string, int>();

			if (this.Count == 0)
			{
				stats.Add(ThePresenter.Properties.Resources.Poll_NoAnswers, 0);
				this._Statistics = stats;

				return;
			}

			List<String> options;

			switch (this.Options.OptionsType)
			{
				case OptionsType.Text:
					foreach (TextAnswerData answer in this)
					{
						// In case someone manage to send answer whitout text
						if (answer.Answer == null) answer.Answer = String.Empty;

						if (stats.ContainsKey(answer.Answer)) stats[answer.Answer]++;
						else stats.Add(answer.Answer, 1);
					}
					break;

				case OptionsType.Canvas:
					stats.Add(Properties.Resources.Poll_AnswersCount, this.Count);
					break;

				case OptionsType.YesNo:
					stats.Add(Properties.Resources.Poll_AnswerOption_Yes, this.Count(i => (i as YesNoAnswerData).Result == true));
					stats.Add(Properties.Resources.Poll_AnswerOption_No,  this.Count(i => (i as YesNoAnswerData).Result == false));
					break;

				case OptionsType.PickOne:
					options = ((SelectOptionsData)Options).Options;
					foreach (String option in options)
					{
						if (!stats.ContainsKey(option))
						{
							stats.Add(option, this.Count(i => options[(i as PickOneAnswerData).SelectedItemIndex].Equals(option)));
						}
					}
					break;

				case OptionsType.PickSome:
					options = ((SelectOptionsData)Options).Options;
					for (int j = 0; j < options.Count; j++)
					{
						if (!stats.ContainsKey(options[j]))
						{
							stats.Add(options[j], this.Count(i => (i as PickSomeAnswerData).Options[j]));
						}
					}
					break;

				default:
					break;
			}

			this._Statistics = stats;
		}

		/// <summary>
		/// Processes the answer.
		/// </summary>
		/// <param name="A">The A.</param>
		internal void ProcessAnswer(AnswerData A)
		{
			if (this.Count(i => (i as AnswerData).AnswerSource.Equals(A.AnswerSource)) == 0)
			{
				this.Add(A);
				UpdateStats();
				OnPropertyChanged(new PropertyChangedEventArgs("Statistics"));
				OnPropertyChanged(new PropertyChangedEventArgs("Count"));
			}
		}
		#endregion
	}
}
